home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / nos042_s / tcpcmd.c < prev    next >
C/C++ Source or Header  |  1994-09-16  |  8KB  |  322 lines

  1. /* TCP control and status routines
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4.  
  5. /****************************************************************************
  6. *    $Id: tcpcmd.c 1.2 93/07/16 11:51:10 ROOT_DOS Exp $
  7. *    09 May 93    1.2        GT    Fix warnings.                                    *
  8. ****************************************************************************/
  9.  
  10. #include <stdio.h>
  11. #include "global.h"
  12. #include "timer.h"
  13. #include "mbuf.h"
  14. #include "netuser.h"
  15. #include "internet.h"
  16. #include "tcp.h"
  17. #include "cmdparse.h"
  18. #include "commands.h"
  19.  
  20. static int doirtt __ARGS((int argc,char *argv[],void *p));
  21. static int domss __ARGS((int argc,char *argv[],void *p));
  22. static int dortt __ARGS((int argc,char *argv[],void *p));
  23. static int dotcpkick __ARGS((int argc,char *argv[],void *p));
  24. static int dotcpreset __ARGS((int argc,char *argv[],void *p));
  25. static int dotcpstat __ARGS((int argc,char *argv[],void *p));
  26. static int dotcptr __ARGS((int argc,char *argv[],void *p));
  27. static int dowindow __ARGS((int argc,char *argv[],void *p));
  28. static int dosyndata __ARGS((int argc,char *argv[],void *p));
  29. static int tstat __ARGS((void));
  30.  
  31. /* TCP subcommand table */
  32. static struct cmds Tcpcmds[] = {
  33.     { "irtt",        doirtt,        0, 0,    NULLCHAR },
  34.     { "kick",        dotcpkick,    0, 2,    "tcp kick <tcb>" },
  35.     { "mss",        domss,        0, 0,    NULLCHAR },
  36.     { "reset",    dotcpreset,    0, 2,    "tcp reset <tcb>" },
  37.     { "rtt",        dortt,        0, 3,    "tcp rtt <tcb> <val>" },
  38.     { "status",    dotcpstat,    0, 0,    NULLCHAR },
  39.     { "syndata",    dosyndata,    0, 0,    NULLCHAR },
  40.     { "trace",    dotcptr,    0, 0,    NULLCHAR },
  41.     { "window",    dowindow,    0, 0,    NULLCHAR },
  42.     { NULLCHAR },
  43. };
  44. int
  45. dotcp(argc,argv,p)
  46. int argc;
  47. char *argv[];
  48. void *p;
  49. {
  50.     return subcmd(Tcpcmds,argc,argv,p);
  51. }
  52. static int
  53. dotcptr(argc,argv,p)
  54. int argc;
  55. char *argv[];
  56. void *p;
  57. {
  58.     return setbool(&Tcp_trace,"TCP state tracing",argc,argv);
  59. }
  60.  
  61. /* Eliminate a TCP connection */
  62. static int
  63. dotcpreset(argc,argv,p)
  64. int argc;
  65. char *argv[];
  66. void *p;
  67. {
  68.     register struct tcb *tcb;
  69.  
  70.     tcb = (struct tcb *)ltop(htol(argv[1]));
  71.     if(!tcpval(tcb)){
  72.         tprintf(Notval);
  73.         return 1;
  74.     }
  75.     reset_tcp(tcb);
  76.     return 0;
  77. }
  78.  
  79. /* Set initial round trip time for new connections */
  80. static int
  81. doirtt(argc,argv,p)
  82. int argc;
  83. char *argv[];
  84. void *p;
  85. {
  86.     struct tcp_rtt *tp;
  87.  
  88.     setlong(&Tcp_irtt,"TCP default irtt",argc,argv);
  89.     if(argc < 2){
  90.         for(tp = &Tcp_rtt[0];tp < &Tcp_rtt[RTTCACHE];tp++){
  91.             if(tp->addr != 0){
  92.                 if(tprintf("%s: srtt %lu mdev %lu\n",
  93.                  inet_ntoa(tp->addr),
  94.                  tp->srtt,tp->mdev) == EOF)
  95.                     break;
  96.             }
  97.         }
  98.     }
  99.     return 0;
  100. }
  101.  
  102. /* Set smoothed round trip time for specified TCB */
  103. static int
  104. dortt(argc,argv,p)
  105. int argc;
  106. char *argv[];
  107. void *p;
  108. {
  109.     register struct tcb *tcb;
  110.  
  111.     tcb = (struct tcb *)ltop(htol(argv[1]));
  112.     if(!tcpval(tcb)){
  113.         tprintf(Notval);
  114.         return 1;
  115.     }
  116.     tcb->srtt = atol(argv[2]);
  117.     return 0;
  118. }
  119.  
  120. /* Force a retransmission */
  121. static int
  122. dotcpkick(argc,argv,p)
  123. int argc;
  124. char *argv[];
  125. void *p;
  126. {
  127.     register struct tcb *tcb;
  128.  
  129.     tcb = (struct tcb *)ltop(htol(argv[1]));
  130.     if(kick_tcp(tcb) == -1){
  131.         tprintf(Notval);
  132.         return 1;
  133.     }
  134.     return 0;
  135. }
  136.  
  137. /* Set default maximum segment size */
  138. static int
  139. domss(argc,argv,p)
  140. int argc;
  141. char *argv[];
  142. void *p;
  143. {
  144.     return setshort(&Tcp_mss,"TCP MSS",argc,argv);
  145. }
  146.  
  147. /* Set default window size */
  148. static int
  149. dowindow(argc,argv,p)
  150. int argc;
  151. char *argv[];
  152. void *p;
  153. {
  154.     return setshort(&Tcp_window,"TCP window",argc,argv);    
  155. }
  156.  
  157. static int
  158. dosyndata(argc,argv,p)
  159. int argc;
  160. char *argv[];
  161. void *p;
  162. {
  163.     return setbool(&Tcp_syndata,"TCP syn+data piggybacking",argc,argv);
  164. }
  165.  
  166.  
  167. /* Display status of TCBs */
  168. static int
  169. dotcpstat(argc,argv,p)
  170. int argc;
  171. char *argv[];
  172. void *p;
  173. {
  174.     register struct tcb *tcb;
  175.  
  176.     if(argc < 2){
  177.         tstat();
  178.     } else {
  179.         tcb = (struct tcb *)ltop(htol(argv[1]));
  180.         if(tcpval(tcb))
  181.             st_tcp(tcb);
  182.         else
  183.             tprintf(Notval);
  184.     }
  185.     return 0;
  186. }
  187.  
  188. /* Dump TCP stats and summary of all TCBs
  189. /*     &TCB Rcv-Q Snd-Q  Local socket           Remote socket          State
  190.  *     1234     0     0  xxx.xxx.xxx.xxx:xxxxx  xxx.xxx.xxx.xxx:xxxxx  Established
  191.  */
  192. static int
  193. tstat()
  194. {
  195.     register int i;
  196.     register struct tcb *tcb;
  197.     int j;
  198.  
  199.     for(j=i=1;i<=NUMTCPMIB;i++){
  200.         if(Tcp_mib[i].name == NULLCHAR)
  201.             continue;
  202.         tprintf("(%2u)%-20s%10lu",i,Tcp_mib[i].name,
  203.          Tcp_mib[i].value.integer);
  204.         if(j++ % 2)
  205.             tprintf("     ");
  206.         else
  207.             tprintf("\n");
  208.     }
  209.     if((j % 2) == 0)
  210.         tprintf("\n");
  211.  
  212.     tprintf("    &TCB Rcv-Q Snd-Q  Local socket           Remote socket          State\n");
  213.     for(tcb=Tcbs;tcb != NULLTCB;tcb = tcb->next){
  214.         tprintf("%8lx%6u%6u  ",ptol(tcb),tcb->rcvcnt,tcb->sndcnt);
  215.         tprintf("%-23s",pinet(&tcb->conn.local));
  216.         tprintf("%-23s",pinet(&tcb->conn.remote));
  217.         tprintf("%-s",Tcpstates[tcb->state]);
  218.         if(tcb->state == TCP_LISTEN && tcb->flags.clone)
  219.             tprintf(" (S)");
  220.         if(tprintf("\n") == EOF)
  221.             return 0;
  222.     }
  223.     return 0;
  224. }
  225. /* Dump a TCP control block in detail */
  226. void
  227. st_tcp(tcb)
  228. struct tcb *tcb;
  229. {
  230.     int32 sent,recvd;
  231.  
  232.     if(tcb == NULLTCB)
  233.         return;
  234.     /* Compute total data sent and received; take out SYN and FIN */
  235.     sent = tcb->snd.una - tcb->iss;    /* Acknowledged data only */
  236.     recvd = tcb->rcv.nxt - tcb->irs;
  237.     switch(tcb->state){
  238.     case TCP_LISTEN:
  239.     case TCP_SYN_SENT:    /* Nothing received or acked yet */
  240.         sent = recvd = 0;    
  241.         break;
  242.     case TCP_SYN_RECEIVED:
  243.         recvd--;    /* Got SYN, no data acked yet */
  244.         sent = 0;
  245.         break;
  246.     case TCP_ESTABLISHED:    /* Got and sent SYN */
  247.     case TCP_FINWAIT1:    /* FIN not acked yet */
  248.         sent--;
  249.         recvd--;
  250.         break;
  251.     case TCP_FINWAIT2:    /* Our SYN and FIN both acked */
  252.         sent -= 2;
  253.         recvd--;
  254.         break;
  255.     case TCP_CLOSE_WAIT:    /* Got SYN and FIN, our FIN not yet acked */
  256.     case TCP_CLOSING:
  257.     case TCP_LAST_ACK:
  258.         sent--;
  259.         recvd -= 2;
  260.         break;
  261.     case TCP_TIME_WAIT:    /* Sent and received SYN/FIN, all acked */
  262.         sent -= 2;
  263.         recvd -= 2;
  264.         break;
  265.     }
  266.     tprintf("Local: %s",pinet(&tcb->conn.local));
  267.     tprintf(" Remote: %s",pinet(&tcb->conn.remote));
  268.     tprintf(" State: %s\n",Tcpstates[tcb->state]);
  269.     tprintf("      Init seq    Unack     Next Resent CWind Thrsh  Wind  MSS Queue      Total\n");
  270.     tprintf("Send:");
  271.     tprintf("%9lx",tcb->iss);
  272.     tprintf("%9lx",tcb->snd.una);
  273.     tprintf("%9lx",tcb->snd.nxt);
  274.     tprintf("%7lu",tcb->resent);
  275.     tprintf("%6u",tcb->cwind);
  276.     tprintf("%6u",tcb->ssthresh);
  277.     tprintf("%6u",tcb->snd.wnd);
  278.     tprintf("%5u",tcb->mss);
  279.     tprintf("%6u",tcb->sndcnt);
  280.     tprintf("%11lu\n",sent);
  281.  
  282.     tprintf("Recv:");
  283.     tprintf("%9lx",tcb->irs);
  284.     tprintf("         ");
  285.     tprintf("%9lx",tcb->rcv.nxt);
  286.     tprintf("%7lu",tcb->rerecv);
  287.     tprintf("      ");
  288.     tprintf("      ");
  289.     tprintf("%6u",tcb->rcv.wnd);
  290.     tprintf("     ");
  291.     tprintf("%6u",tcb->rcvcnt);
  292.     tprintf("%11lu\n",recvd);
  293.  
  294.     if(tcb->reseq != (struct reseq *)NULL){
  295.         register struct reseq *rp;
  296.  
  297.         tprintf("Reassembly queue:\n");
  298.         for(rp = tcb->reseq;rp != (struct reseq *)NULL; rp = rp->next){
  299.             if(tprintf("  seq x%lx %u bytes\n",
  300.              rp->seg.seq,rp->length) == EOF)
  301.                 return;
  302.         }
  303.     }
  304.     if(tcb->backoff > 0)
  305.         tprintf("Backoff %u ",tcb->backoff);
  306.     if(tcb->flags.retran)
  307.         tprintf("Retrying ");
  308.     switch(tcb->timer.state){
  309.     case TIMER_STOP:
  310.         tprintf("Timer stopped ");
  311.         break;
  312.     case TIMER_RUN:
  313.         tprintf("Timer running (%ld/%ld ms) ",
  314.          (long)read_timer(&tcb->timer),
  315.          (long)dur_timer(&tcb->timer));
  316.         break;
  317.     case TIMER_EXPIRE:
  318.         tprintf("Timer expired ");
  319.     }
  320.     tprintf("SRTT %ld ms Mean dev %ld ms\n",tcb->srtt,tcb->mdev);
  321. }
  322.